
	/***********************************************************************************************
	 	
		Factory: jsl.Object
											
		Generics:
			obj		Object								(v)										- sid: 7.0
			name	getName								()										- sid: 7.0
			obj		setName								(name*)								- sid: 7.0
			oid		getOid								()										- sid: 7.0
			obj		setOid								(oid*)								- sid: 7.0
		
		Info:	
			p			getPrototype					()										- sid: 7.0
			c			getClass							()										- sid: 7.0
			name	getClassName					()										- sid: 7.0
		
		Serial:
			id		getSerialId						()										- sid: 1.0
			obj		setSerialId						(sid*)								- sid: 1.0
		
		Cloning:									
			obj   clone									(depth*)							- sid: 7.0
			obj		copy									(params..*)						- sid: 7.0
			obj   map										(rule*)								- sid: 7.0
		
		Modifiers:
			obj		merge									(obj, filter*)	 			- sid: 7.0
			obj		transform							(rule)								- sid: 7.0
			obj		clear									(filter*)							- sid: 7.0	
		
		Queries:	
			b			isEmpty								()										- sid: 7.0
			idx		isIn									(list..)							- sid: 7.0			
			b			instanceOf						(types..)							- sid: 7.0
		
		Enumeration:	
			obj		setEnumerationFlags		(flags*)							- sid: 7.0
			obj		setEnumerationRule		(rule*)								- sid: 7.0
			flags	getEnumerationFlags		()										- sid: 7.0
			rule	getEnumerationRule		()										- sid: 7.0
			
			obj		hideProperty					(id)									- sid: 7.0
			obj		hideProperties				(ids..*)							- sid: 7.0	
			obj		unhideProperty				(id)									- sid: 7.0
			obj		unhideProperties			(ids..*)							- sid: 7.0
			obj		resetHideFlag					(ids..*)							- sid: 7.0
			b			isEnumerable					(id)									- sid: 7.0

			it		getIterator						(filter*)							- sid: 7.0
			list	enumerate							(filter*)							- sid: 7.0 
			obj		walk									(action)							- sid: 7.0
			b			test									(rule)								- sid: 7.0
																				
		Legend:			
			filter:	function/string		- b	function(id, v)
			action:	function					- b function(id, v)
			rule:		function					- b	function(id, v)
			
			flags: u?p?n? | all				- underscored, prototype, native
								
		@sys:
			@sys: Explorer 8.0.6 	- the for/in loop enumerates the new properties added 					
			@sys:	Opera 10.63 		- the prototype property of functions are enumerable in for/in loops
			@sys:	Firefox 3.6.12 	- the properties lineNumber , stack, fileName of errors are enumerable in for/in loops
			@sys: Firefox 3.6.12	- in a string object, the for/in loop enumerate also 0, 1, 2, 3, ..
						
	************************************************************************************************/
 	
  //-------------------------------------------------------------------------------
  jsl.Object = function(v) {
  	try {  		
  		var proto, rv
  		//@d[
	    if(arguments.length > 1)	throw jsl.ParamError()//@d]
			
	    if(arguments.length) {
				
				if(v == null)								throw jsl.ParamError("NullValue:v")
	    	else if(v.__augmented)			return v
				else if(jsl.isError(v)) 		return jsl.Error(v)
			 	else if(jsl.isArray(v))  		{ if(!jsl.__libs["lang"]) jsl.require("lang"); return jsl.Array(v) 		}
		    else if(jsl.isBoolean(v))		{ if(!jsl.__libs["lang"]) jsl.require("lang"); return jsl.Boolean(v) 	}
		    else if(jsl.isDate(v))  		{ if(!jsl.__libs["lang"]) jsl.require("lang"); return jsl.Date(v) 		}
		    else if(jsl.isFunction(v))	{ if(!jsl.__libs["lang"]) jsl.require("lang"); return jsl.Function(v) }
		    else if(jsl.isNumber(v))		{ if(!jsl.__libs["lang"]) jsl.require("lang"); return jsl.Number(v) 	}
		    else if(jsl.isString(v))  	{ if(!jsl.__libs["lang"]) jsl.require("lang"); return jsl.String(v) 	}
				else rv = v	
				
			}
			else
				rv = {}
									    			 	    	    
			proto = jsl.Object.prototype
			
    	for(var id in proto)
    		if(proto.hasOwnProperty(id))
					rv[id] = proto[id]
			
			rv.__native = arguments.callee.__native			
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
  }
  //-------------------------------------------------------------------------------
	jsl.Object.PROPERTY_REMOVE				= {}
	jsl.Object.PROPERTY_NOMAP					= {}
	jsl.Object.__name									= "jsl.Object" 
  //-------------------------------------------------------------------------------	
	jsl.Object.prototype.__augmented	= true	
  //-------------------------------------------------------------------------------
  jsl.Object.prototype.getName = function() {
    try {
    	//@d[
      if(arguments.length)  throw jsl.ParamError()//@d]
      
			//@sys: Firefox 4 - Error.name is undefined. In other error type is all normal
			//			ex: SyntaxError,name = "SyntaxError"
      if(!this.__name)
							if(jsl.isArray(this))			this.__name = "Array"
				else	if(jsl.isBoolean(this))		this.__name = "Boolean"
				else	if(jsl.isDate(this))			this.__name = "Date"
				else	if(jsl.isError(this))			this.__name = this.name || "Error"
				else	if(jsl.isFunction(this))	this.__name = "anonymous"
				else	if(jsl.isNumber(this))		this.__name = "Number"
				else	if(jsl.isRegExp(this))		this.__name = "RegExp"
				else	if(jsl.isString(this))		this.__name = "String"
				else														this.__name = "Object"
	    	    
	    return this.__name
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
  //-------------------------------------------------------------------------------
  jsl.Object.prototype.setName = function(name) {
    try {//@d[
      if(arguments.length > 1)  throw jsl.ParamError()
      if(arguments.length)			jsl.validate(name, "s+", "name")//@d]

      if(arguments.length)	this.__name = name + ""
      else 									delete this.__name
      
      return this
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }	
  //-------------------------------------------------------------------------------
  jsl.Object.prototype.getOid = function() {
    try {//@d[
      if(arguments.length)  throw jsl.ParamError()//@d]
      return this.__oid || null
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
  //-------------------------------------------------------------------------------
  jsl.Object.prototype.setOid = function(oid) {
    try {
    	var b, obj
    	//@d[
      if(arguments.length > 1)	throw jsl.ParamError()
			
      if(arguments.length) {
			
				jsl.validate(oid, "s+", "oid")		    
			
				b = jsl.__objs.hasOwnProperty(oid)
				if(b && jsl.__objs[oid] !== this)	throw jsl.ParamError("AlreadyDefined:oid")
			}//@d]
			      
      if(oid != this.__oid) {
      	
				if(this.__oid)	delete jsl.__objs[this.__oid]
	      if(oid) 				jsl.__objs[oid] = this
				
	      this.__oid = oid ? oid + "" : null
      }
      
    	return this
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }	
  //-------------------------------------------------------------------------------
  jsl.Object.prototype.getPrototype = function() {
    try {//@d[
      if(arguments.length)	throw jsl.ParamError()
			jsl.validate(this.constructor, "f", "constructor")//@d]	
			
      return this.constructor.prototype
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }	
  //-------------------------------------------------------------------------------
  jsl.Object.prototype.getClass = function() {
    try {//@d[
      if(arguments.length)  throw jsl.ParamError()//@d]
      return this.__class || null
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
  //-------------------------------------------------------------------------------
  jsl.Object.prototype.getClassName = function() {
    try {//@d[
      if(arguments.length)  throw jsl.ParamError()//@d]
      return this.__class ? this.__class.getName() : null
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
  //-------------------------------------------------------------------------------
  jsl.Object.prototype.getSerialId = function() {
    try {//@d[
      if(arguments.length)  throw jsl.ParamError()//@d]
      return this.__sid || null
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
  //-------------------------------------------------------------------------------
  jsl.Object.prototype.setSerialId = function(sid) {
    try {//@d[
      if(arguments.length > 1)  throw jsl.ParamError()
			if(arguments.length)			jsl.validate(sid, "qid", "sid")//@d]
			
			if(arguments.length)	this.__sid = sid + ""
			else									delete this.__sid
			
      return this
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.clone = function(depth) {
		try {
			var id, obj, c, b, objs, len, d
			//@d[
			if(arguments.length > 1)	throw	jsl.ParamError()
			if(arguments.length)			jsl.validate(depth, "b|i+", "depth")
			
			//the constructor property can be setted to any value
			jsl.validate(this.constructor, "f", "constructor", jsl.MisuseError)//@d]	

			c = this.constructor
			
						if(c === Array) 					obj = this.slice()
			else 	if(c === Boolean)					obj	= new Boolean(this.valueOf())
			else 	if(c === Date)						obj	= new Date(+this)
			else 	if(c === Error)						obj	= new Error(this.message)
			else 	if(c === TypeError)				obj	= new TypeError(this.message)
			else 	if(c === SyntaxError)			obj	= new SyntaxError(this.message)
			else 	if(c === EvalError)				obj	= new EvalError(this.message)
			else 	if(c === RangeError)			obj	= new RangeError(this.message)
			else 	if(c === ReferenceError)	obj	= new ReferenceError(this.message)	
			else 	if(c === URIError)				obj	= new URIError(this.message)	
			else 	if(c === Number)					obj	= new Number(+this)
			else	if(c === RegExp) 					obj = new RegExp(this) 
			else 	if(c === String) 					obj = this.slice()
			else  
				
				//a native javascript function cannot be cloned -> toString: function() { [native code]	} 
				if(c === Function)
					try 			{ eval("obj = " + this) }
					catch(e)	{ obj = this 						}
			
				else {			
					jsl.__vars.f.prototype 	= this.constructor.prototype
					obj 										= new jsl.__vars.f()
				}
						
			if(arguments.length && depth.valueOf()) {
				
				objs 	= arguments.callee.__objs
				len		= objs.length
				d			= jsl.isBoolean(depth) ? depth : depth - 1

				arguments.callee.__status++
								
				for(id in this) 
					if(!this.hasOwnProperty || this.hasOwnProperty(id))
						
						//@sys: Explorer 8 - if clone also the functions -> infinite loop because in a depth >= 3 also
						//clone, clone.__status and clone.__objs are cloned. __objs is enumerated meanwhile it grows
						//the functions are seen as code and are copied without cloning in a clone depth.
						//only the first function can be cloned but all sub-functions are copied 
						if(!jsl.isFunction(this[id]) && jsl.isObject(this[id])) {
							
							for(b = 0; b < len; b++)
								if(objs[b] === this[id]) 
									break									
							
							if(b === len) {
								//first cache the new object and then clone his properties otherwise can occour an infinite loop 
								//ex: jsl.Node parent->child: parent.__childs[0].__parent ? but parent is not already cached 
								objs["_" + objs.length] = obj[id]
								objs.push(this[id])
								obj[id] = arguments.callee.call(this[id], d)
							}
							else	
								obj[id] = objs["_" + b]
						}
						else
							obj[id] = this[id]		
													
				arguments.callee.__status--

				if(!arguments.callee.__status) 
					arguments.callee.__objs = []
			}				
			else				
				for(id in this) 
					if(!this.hasOwnProperty || this.hasOwnProperty(id)) 
						obj[id] = this[id]				
			
			return obj
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	} 
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.clone.__status = 0
	jsl.Object.prototype.clone.__objs 	= []
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.copy = function() {
		try {
			var id, obj, c
			//@d[			
			//@the constructor property can be setted to any value
			jsl.validate(this.constructor, "f", "constructor", jsl.MisuseError)//@d]
			
			c = this.constructor
			
						if(c === Array) 					obj = this.slice()
			else 	if(c === Boolean)					obj	= new Boolean(this.valueOf())
			else 	if(c === Date)						obj	= new Date(+this)
			else 	if(c === Error)						obj	= new Error(this.message)
			else 	if(c === TypeError)				obj	= new TypeError(this.message)
			else 	if(c === SyntaxError)			obj	= new SyntaxError(this.message)
			else 	if(c === EvalError)				obj	= new EvalError(this.message)
			else 	if(c === RangeError)			obj	= new RangeError(this.message)
			else 	if(c === ReferenceError)	obj	= new ReferenceError(this.message)	
			else 	if(c === URIError)				obj	= new URIError(this.message)	
			else 	if(c === Number)					obj	= new Number(+this)
			else	if(c === RegExp) 					obj = new RegExp(this) 
			else 	if(c === String) 					obj = this.slice()
			else
			
				//a native javascript function cannot be cloned -> toString: function() { [native code]	} 
				if(c === Function)
					try 			{ eval("obj = " + this) }
					catch(e)	{ obj = this 						}
			
				else {			
					jsl.__vars.f.prototype 	= this.constructor.prototype
					obj 										= new jsl.__vars.f()
				
					try 			{ this.constructor.apply(obj, arguments)			}
					catch(e) 	{ throw jsl.ScriptError("BadConstructor", e)	}				
				
				}
			
			for(id in this) 
				if(!this.hasOwnProperty || this.hasOwnProperty(id)) 
					obj[id] = this[id]

			return obj
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.map = function(rule) {
		try {
			var obj, c
			//@d[
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(rule, "f", "rule")
			//the constructor property can be setted to any value
			jsl.validate(this.constructor, "f", "constructor")//@d]

			c = this.constructor
			
						if(c === Array) 					obj = this.slice()
			else 	if(c === Boolean)					obj	= new Boolean(this.valueOf())
			else 	if(c === Date)						obj	= new Date(this.getTime())
			else 	if(c === Error)						obj	= new Error(this.message)
			else 	if(c === TypeError)				obj	= new TypeError(this.message)
			else 	if(c === SyntaxError)			obj	= new SyntaxError(this.message)
			else 	if(c === EvalError)				obj	= new EvalError(this.message)
			else 	if(c === RangeError)			obj	= new RangeError(this.message)
			else 	if(c === ReferenceError)	obj	= new ReferenceError(this.message)	
			else 	if(c === URIError)				obj	= new URIError(this.message)	
			else 	if(c === Number)					obj	= new Number(+this)
			else	if(c === RegExp) 					obj = new RegExp(this) 
			else 	if(c === String) 					obj = this.slice()
			else  
				
				//a native javascript function cannot be cloned -> toString: function() { [native code]	} 
				if(c === Function)
					try 			{ eval("obj = " + this) }
					catch(e)	{ obj = this 						}
			
				else {			
					jsl.__vars.f.prototype 	= this.constructor.prototype
					obj 										= new jsl.__vars.f()
				}
							
			jsl.Object.walk(this, function(id, v, last) {
				
				if(rule)				
					try				{ var rv = rule(id, v, last)									}
					catch(e) 	{ throw jsl.ScriptError("BadScript:rule", e)	}				
				else
					rv = v 

				if(rv !== jsl.Object.PROPERTY_NOMAP)
					obj[id] = rv
			})
			
			return obj
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
	jsl.Object.prototype.merge = function(obj, filter) {
		try {
			var id, target
			//@d[
			if(!arguments.length || arguments.length > 2)	throw	jsl.ParamError()
			jsl.validate(obj, "o", "obj")
			
			if(arguments.length === 2)	jsl.validate(filter, "f", "filter")//@d]
			
			target = this
			
			jsl.Object.walk(obj, function(id, v, last) {
				
				if(filter) 
					try 			{ if(filter(id, v, last))	target[id] = v				}
					catch(e) 	{ throw jsl.ScriptError("BadScript:filter", e)	}
				
				else
					target[id] = v
			})

			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.transform = function(rule) {
		try {
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(rule, "f", "rule")//@d]						
			
			jsl.Object.walk(this, function(id, v, last) {
				//a prototype property cannot be deleted or transformed
				if(!this.hasOwnProperty || this.hasOwnProperty(id)) {				
					try				{ var rv = rule(id, v, last) 										}
					catch(e) 	{ throw jsl.ScriptError("BadScript:filter", e)	}				
					
					if(rv === jsl.Object.PROPERTY_REMOVE)	delete this[id]
					else																	this[id] = rv
				}
			})

			return this			
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.clear = function(filter) {
		try {//@d[
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(filter, "f", "filter")//@d]
						
			jsl.Object.walk(this, function(id, v, last) {				
				//a prototype property cannot be deleted or transformed
				if(!this.hasOwnProperty || this.hasOwnProperty(id)) {
					try				{ var rv = filter ? filter(id, v, last) : true	}
					catch(e) 	{ throw jsl.ScriptError("BadScript:filter", e)	}				
					
					if(rv) delete this[id]
				}
			})
			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.isEmpty = function() {
		try {//@d[
			if(arguments.length)	throw jsl.ParamError()//@d]
			
			var n = 0
			jsl.Object.walk(this, function() { n++ })
			return !n						
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.isIn = function() {
		try {
			var args, len, v, arg, len2
			//@d[
			if(!arguments.length)	throw jsl.ParamError()//@d]

			args 	= arguments
			len		= args.length
			v			= 0

			for(var a = 0, i = 0; a < len && !v; a++, i++)
				if(args[a] instanceof Array) {
					
					arg 	= args[a]
					len2	= arg.length
										
					for(var b = 0; b < len2 && !v; b++)
						if(this == arg[b])
							v = i + b + 1
					
					i += arg.length - 1
				}
				else if(this == args[a])
					v = i + 1

			return v
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.instanceOf = function() {
		try {
			var fs, len, v
			//@d[
			if(!arguments.length)	throw jsl.ParamError()//@d]
			
			fs	= arguments
			len	= arguments.length
			v		= false
			
			for(var a = 0; a < len && !v; a++) {
				
				//the cicle must validate all parameters
				//@d[					
				jsl.validate(fs[a], "f", "types[" + a + "]")//@d]
				v = this instanceof fs[a]
			}
			
			return v
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}	
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.setEnumerationFlags = function(flags) {
		try {//@d[
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length) {
				
				jsl.validate(flags, "s+", "flags")
				if(!(/^[upn]{0,3}$|^\*$/).test(flags))	throw jsl.ParamError("BadValue:flags")
				
				if(flags !== "*")
					for(var i = 0, fgs = {}; i < flags.length; fgs[flags.charAt(i)] = true, i++)
						if(fgs.hasOwnProperty(flags.charAt(i)))					
							throw jsl.ParamError("BadValue:flags")
			}//@d]
			
			//if eflags is deleted we can read the eflags of the prototype			
			if(flags != null)	this.__eflags = flags + ""
			else							delete this.__eflags			
			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.setEnumerationRule = function(rule) {
		try {//@d[
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(rule, "f", "rule")//@d]
			
			if(rule)	this.__erule = rule
			else			delete this.__erule
			
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.getEnumerationFlags = function() {
		try {
			var flags
			//@d[
			if(arguments.length)	throw jsl.ParamError()//@d]
			
			flags = this.__eflags			
			
			if(flags === "*")	flags = "upn"
			else if(!flags)		flags = ""

			return flags
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.getEnumerationRule = function() {
		try {//@d[
			if(arguments.length)	throw jsl.ParamError()//@d]
			return this.__erule || null
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
  jsl.Object.prototype.hideProperty = function(id) {
    try {//@d[      
      if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(id, "s+", "id")//@d]
			
			this["__h_" + id] = true
      return this
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
	//-------------------------------------------------------------------------------
  jsl.Object.prototype.hideProperties = function() {
    try {
      var len, ids
      
      if(!arguments.length)
      	jsl.Object.walk(this, function(id) { this["__h_" + id] = true })
      else {
			
				ids = arguments
				len	= ids.length
											
				for(var a = 0; a < len; a++) {
					//@d[
					jsl.validate(ids[a], "s+", "ids[" + a + "]")//@d]
					this["__h_" + ids[a]] = true
				}
      }
      
      return this
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
	//-------------------------------------------------------------------------------
  jsl.Object.prototype.unhideProperty = function(id) {
    try {//@d[      
      if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(id, "s+", "id")//@d]
			
			//no deletion because we want override the hide setting of the proto
			this["__h_" + id] = null			
      return this
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
	//-------------------------------------------------------------------------------
  jsl.Object.prototype.unhideProperties = function() {
    try {
      var a, len, ids
      
			//no walk in delete all beacause the walk do not enumerates the hidden properties
			//@sys:	Explorer 8 - enumerates the new propertie added to the object inside the for/in loop
      if(!arguments.length) { 				
				
				for(var id in this) 									
					if(id.slice(0, 4) !== "__h_") 
						this["__h_" + id] = null
			}
      else {
				
				ids = arguments
				len	= ids.length
				
				for(a = 0; a < len; a++) {
					//@d[
					jsl.validate(ids[a], "s+", "ids[" + a + "]")//@d]					
					this["__h_" + ids[a]] = null
				}
      }
      
      return this
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }										 
	//-------------------------------------------------------------------------------
  jsl.Object.prototype.resetHideFlag = function() {
    try {      
			var a, id
			
			if(arguments.length)			
				for(a = arguments.length - 1; a >= 0; a--) {
					
					id = arguments[a]//@d[ 		
					jsl.validate(id, "s+", "ids[" + a + "]")//@d]
					
					//@sys: Explorer 8 - some native objects not have the 'hasOwnProperty' method
					//			example: event object passes in a listener registered with attachEvent
					if(!this.hasOwnProperty || this.hasOwnProperty("__h_" + id))
						delete this["__h_" + id]					
				}
			else	
				for(id in this)
					if(!this.hasOwnProperty || this.hasOwnProperty("__h_" + id))
						delete this["__h_" + id]
						
      return this
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
	//-------------------------------------------------------------------------------
  jsl.Object.prototype.isEnumerable = function(id) {
    try {      
			var er, u, p, n, isN, all, rv, nat
      //@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(id, "s+", "id")//@d]

			er	= this.__erule 
			nat	= this.__native
			all	= this.__eflags === "*"
			
			//if we call an extended method on a regular object we not have __native. An iterator
			//could enumerate some native properties setted by other extended methods called on the object before. 
			//if the lang lib was not loaded, no extended methods are called, we not have the need of __native
			if(!nat) 
				if(jsl.isError(this))							nat = jsl.Error.__native
				else if(jsl.__libs["lang"]) {
				
								if(jsl.isArray(this))			nat = jsl.Array.__native
					else 	if(jsl.isBoolean(this))		nat = jsl.Boolean.__native
					else 	if(jsl.isDate(this))			nat = jsl.Date.__native
					else	if(jsl.isFunction(this))	nat = jsl.Function.__native
					else 	if(jsl.isNumber(this))		nat = jsl.Number.__native
					else 	if(jsl.isString(this))		nat = jsl.String.__native
					else														nat = jsl.Object.__native
				}
				else
					nat = jsl.Object.__native
									
			isN	= nat && nat.hasOwnProperty(id)
			u		= this.__eflags && (all || this.__eflags.indexOf("u") !== -1) 
			p		= this.__eflags && (all || this.__eflags.indexOf("p") !== -1) 
			n		= this.__eflags && (all || this.__eflags.indexOf("n") !== -1) 
			
			//the enumeration rule must execute before the in/hasOwnProperty	row because in the
			//rule a property can be deleted												
			rv 	= (u 		? true 				: id.charAt(0) !== "_")															&&
						(!er	? true 				: er.call(this, id, this[id]))											&&
						(p 		? id in this	: !this.hasOwnProperty || this.hasOwnProperty(id))	&& 
						(n 		? true 				: !isN)																							&& 
					 	(!this["__h_" + id])
				
      return rv
    }
    catch(e) {
	    jsl.throwError(e, this, arguments)
    }
  }
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.enumerate = function(filter) {
		try {//@d[
			if(arguments.length > 1)	throw jsl.ParamError()
			if(arguments.length)			jsl.validate(filter, "f", "filter")//@d]						
			
			var rv = []
			
			jsl.Object.walk(this, function(id, v, last) {
				if(filter ? filter(id, v, last) : true)
					rv.push(id)			
			})
				
			return rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  //-------------------------------------------------------------------------------
  jsl.Object.prototype.getIterator = function(filter) {
    try {
    	var data, id, it, idx, obj
    	//@d[    	    	
      if(arguments.length > 1)	throw jsl.ParamError()
      if(arguments.length)      jsl.validate(filter, "f", "filter")//@d]		
			
			it 			= { __name: "jsl.ObjectIterator" }
			obj			= this
			data 		= []
			idx			= 0
			
			//All enumeration filters must be considered dynamic into the iteration.
			//The filters could changes inside an iteration: thid can cause hasNext -> true and then next -> EndOfIterationError
			//sys: 	Explorer 8 - for/in loop on a native xml(#document) node throws 'Action not valid for the object'
			//			on a error the system enumerate the function parameters to create the stacktrace but if a parameter is a native xml node.. 
			try {
				if(filter)	{ for(id in this) if(filter.call(this, id, this[id]))	data.push(id)	}
				else 				{ for(id in this) 																		data.push(id)	}
			}
			catch(e) {}
			 
			data.sort()

  		//-------------------------------------------------------------------------------
			it.hasNext = function() {
				try {//@d[
					if(arguments.length)	throw jsl.ParamError()//@d]
					
					var id, isE
					
					isE = jsl.Object.isEnumerable
					
					while(idx < data.length) {
						
						id = data[idx]
							
						if(isE(obj, id) && (filter ? filter.call(obj, id, obj[id]) : true))						
							break
						
						idx++
					}

					return idx < data.length
				}
				catch(e) {
					jsl.throwError(e, this, arguments)
				}
			}
  		//-------------------------------------------------------------------------------
			it.next = function() {
				try {//@d[
					if(arguments.length) throw jsl.ParamError()//@d]
					
					var b = this.hasNext()					
					if(!b)	throw jsl.EndOfIterationError()
					return data[idx++]
				}
				catch(e) {
					jsl.throwError(e, this, arguments)
				}
			}
												
      return it
    }
    catch(e) {
      jsl.throwError(e, this, arguments)
    }
  }
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.walk = function(action) {
		try {
			var it, id
			//@d[			
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(action, "f", "action")//@d]
			
			it = jsl.Object.getIterator(this)
			
			while(it.hasNext()) {
				
				id = it.next()
				
				try 			{	if(action.call(this, id, this[id], !it.hasNext()))	break		}
				catch(e) 	{ throw jsl.ScriptError("BadScript:action", e) 								}
			}
													
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.Object.prototype.test = function(rule) {
		try {
			var rv = false
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(rule, "f", "rule")//@d]
			
			jsl.Object.walk(this, function(id, v, last) { return rv = rule.call(this, id, v, last) })
			
			return !!rv
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
  
	//Object init
	//-------------------------------------------------------------------------------
	;(function() {
		
		var proto 
		
		//__native is a distinct object from prototype. All his properties will not be enumerated
		jsl.Object.__native	= jsl.Object.prototype.copy()		
		proto								= jsl.Object.__native
		
		//properties do not enumerate but do not put on the prototype because if we call the jsl.Object constructor 
		//on an object on wich where used some extended methods, we can have a reset of his internal state. 		
		//Data
		//-------------------------------------------------------------------------------
		proto.__augmented		= undefined
		proto.__eflags			= undefined
		proto.__erule				= function(id) 	{ return id.charAt(0) !== "_" }
		proto.__native			= undefined
		proto.__oid 				= undefined 
		proto.__name 				= undefined 
		proto.__class 			= undefined 
		proto.__sid					= undefined
		
		//@sys: FireFox 3.6 - prototype is an enumerable property
		proto.prototype 		= undefined 
		proto.constructor		= Object
		proto								= jsl.Object.prototype
		
		//Static methods construction 
		for(var id in proto) 
			if(proto.hasOwnProperty(id)) 
				if(id.charAt(0) !== "_" && jsl.isFunction(proto[id])) {
					
					jsl.Object[id] = function(obj) { 
						try {//@d[
							//is tollerate also a primitive value that is converted in the apply function into object 
							if(!arguments.length)	throw jsl.ParamError() 
							if(obj === null)			throw jsl.ParamError("NullValue:obj")//@d]
															
							return arguments.callee.__f.apply(obj, Array.prototype.slice.call(arguments, 1)) 
						}
						catch(e) {
							jsl.throwError(e, this, arguments)
						}
					}
					
				jsl.Object[id].__name	= id
				jsl.Object[id].__f		= proto[id]				
				proto[id].__name 			= id
			}			
	})()
	